home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 40 / Amiga Format CD40 (1999-05-11)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-06].iso / -readerstuff- / paul_qureshi / source / flair.c < prev    next >
C/C++ Source or Header  |  1999-03-27  |  5KB  |  260 lines

  1.  
  2. From: LarsPC@
  3. Reply-To: lars@scala.no
  4. Newsgroups: comp.graphics.algorithms
  5. Subject: Re: Lens Flares
  6. Date: 14 Mar 1996 13:59:22 GMT
  7. Organization: Scala AS, Norway
  8. Message-ID: <4i98nq$k4l@trance.scala.no>
  9. References: <4i7u68$944@tribune.usask.ca>
  10.  
  11. In <4i7u68$944@tribune.usask.ca>, aa266@sfn.saskatoon.sk.ca (Graeme Humphries) writes:
  12.  
  13. >    Does anybody have (or know where I can get) some code or 
  14. >explanations as to how to do lense flares?  They look extremely cool, but 
  15. >I just haven't seen any description of how to do it.
  16.  
  17. This program was written for an Amiga (that I don't have any longer), so
  18. I hope this version is working properly.
  19.  
  20. It does not draw the extra reflections that you see moving around when
  21. you change the flare position. They are positioned at fixed ratios along
  22. a line from the flare through the center of the screen and does not seem
  23. to be all that difficult to add.
  24.  
  25. This program is *slow* :-)  Let me know what you think.
  26.  
  27. -= Lars =-  lars@scala.no
  28.  
  29.  
  30. /*
  31.  * flare.c
  32.  *
  33.  * Lars Hamre, 1995
  34.  * lars@scala.no
  35.  *
  36.  * tab = 4 spaces
  37.  */
  38.  
  39. #include <exec/types.h>
  40. #include <dos/dos.h>
  41. #include <intuition/intuition.h>
  42. #include <graphics/gfx.h>
  43.  
  44. #include <proto/exec.h>
  45. #include <proto/dos.h>
  46. #include <proto/graphics.h>
  47. #include <proto/intuition.h>
  48.  
  49. #include <stdio.h>
  50. #include <stdlib.h>
  51. #include <math.h>
  52. #include <time.h>
  53.  
  54. /*************************************************************************/
  55.  
  56. struct Screen *scr;
  57. struct Window *win;
  58. struct RastPort *rp;
  59. ULONG rgbtab[1 + 3*256 + 1];
  60.  
  61. int Width  = 640;
  62. int Height = 480;
  63.  
  64. /*************************************************************************/
  65.  
  66. // Return random value between -1 and 1
  67.  
  68. double frand1d(LONG x)
  69. {
  70.     LONG s = 71 * x; s = s * 8192 ^ s;
  71.     return 1.0 - ((s*(s*s*15731+789221)+1376312589)& 0x7fffffff)/1073741824.0;
  72. }
  73.  
  74. // Return bandlimited noise. Each integer value has a different
  75. // random number. Values in-between use linear interpolation.
  76.  
  77. double Noise1D(double x)
  78. {
  79.     LONG i;
  80.     double f,n0,n1;
  81.  
  82.     i = floor(x);
  83.     f = x - i;
  84.     n0 = frand1d(i);
  85.     n1 = frand1d(i+1);
  86.  
  87.     return n0 + (n1-n0)*f;
  88. }
  89.  
  90. // Draw the flare
  91.  
  92. void doit(double r)
  93. {
  94.     struct RastPort temprp = *rp;
  95.     UBYTE col[640];
  96.     LONG x, y;
  97.     double dx, dy, d, a, f, v;
  98.  
  99.     double linear = 0.03;
  100.     double gauss  = 0.006;
  101.     double mix    = 0.50;
  102.  
  103.     double ring,rmin,rmax,rmid,rwid;
  104.  
  105.     // ring position and width
  106.  
  107.     rmid = 27;
  108.     rwid = 1.6;
  109.     rmax = rmid + rwid;
  110.     rmin = rmid - rwid;
  111.  
  112.     f = r;
  113.     r = 0;
  114.  
  115.     temprp.Layer = NULL;
  116.     temprp.BitMap = AllocBitMap(640,1,8,0,rp->BitMap);
  117.  
  118.     for (y=0; y<Height; y++)
  119.     {
  120.         dy = Height/2 - y;
  121.         for (x=0; x<Width; x++)
  122.         {
  123.             dx = x - Width/2;
  124.  
  125.             // Get distance from center of flare
  126.  
  127.             d = sqrt(dx*dx + dy*dy) * 0.5; // 0.5 controls diameter
  128.  
  129.             // The center of the flare is modelled as a gaussian
  130.             // bump, and the glow around is a simple falloff.
  131.             // Mix and match as you like.
  132.             //
  133.             // If calculating in RGB try making the bump white
  134.             // and the glow red-orange.
  135.  
  136.             a = exp(-d*d*gauss)*mix + exp(-d*linear)*(1-mix);
  137.  
  138.             // Draw the ring around the flare. An orange-red
  139.             // color is appropriate here as well.
  140.             // Try RGB = {80,20,10} (or was it darker?)
  141.  
  142.             if (d<rmin || d>rmax)
  143.                 ring = 0;
  144.             else
  145.             {
  146.                 ring = fabs(d-rmid)/rwid;
  147.                 ring = 1 - ring*ring*(3 - 2*ring);
  148.                 ring *= 0.10;
  149.             }
  150.  
  151.             a += ring;
  152.  
  153.             // Creates random lines out from the center.
  154.             // v/PI*17 controls the number of lines.
  155.             // v*10 sets the noise frequency
  156.             // *2 is the noise modulation
  157.  
  158.             v = atan2(dx, dy)+PI;
  159.             v = (fmod(v/PI*17 + 1.0 + Noise1D(v*10), 1.0) - 0.5)*2;
  160.             v = fabs(v);
  161.             v = pow(v, 5.0);
  162.  
  163.             // Add lines and fade out over distance.
  164.  
  165.             a += 0.10*v / (1 + d*0.1);
  166.  
  167.             // Clip to maximum value
  168.  
  169.             if (a>1)
  170.                 a = 1;
  171.  
  172.             col[x] = 255.0 * a;
  173.         }
  174.         WritePixelLine8(rp, 0, y, Width, col, &temprp);
  175.     }
  176.     FreeBitMap(temprp.BitMap);
  177. }
  178.  
  179. /*********************************************************/
  180.  
  181. #define GAMMA 1.0 // 1.8
  182.  
  183. // Create a grayscale palette
  184.  
  185. void SetColors(void)
  186. {
  187.     LONG i, r, g, b, p;
  188.  
  189.     for (i=0; i<256; i++)
  190.     {
  191.         r = 255 * pow(i/255.0, 1/GAMMA);
  192.         g = 255 * pow(i/255.0, 1/GAMMA);
  193.         b = 255 * pow(i/255.0, 1/GAMMA);
  194.  
  195.         rgbtab[1 + i*3 + 0] = r<<24;
  196.         rgbtab[1 + i*3 + 1] = g<<24;
  197.         rgbtab[1 + i*3 + 2] = b<<24;
  198.     }
  199.     rgbtab[0] = (256 << 16) | 0;
  200.     LoadRGB32(&scr->ViewPort, rgbtab);
  201. }
  202.  
  203. void main(void)
  204. {
  205.     srand(time(0));
  206.     if (scr = OpenScreenTags(NULL,
  207.         SA_Width,  640,
  208.         SA_Height, 480,
  209.         SA_Depth, 8,
  210.         SA_DisplayID, VGAPRODUCT_KEY,
  211.         SA_ShowTitle, FALSE,
  212.         TAG_END))
  213.     {
  214.         SetColors();
  215.  
  216.         if (win = OpenWindowTags(NULL,
  217.             WA_CustomScreen, scr,
  218.             WA_IDCMP,  IDCMP_RAWKEY,
  219.             WA_Activate,    TRUE,
  220.             WA_Borderless,    TRUE,
  221.             WA_Backdrop,    TRUE,
  222.             TAG_END))
  223.         {
  224.             struct IntuiMessage *imsg;
  225.             BOOL running = TRUE;
  226.             double r=1;
  227.  
  228.             rp = win->RPort;
  229.  
  230.             doit(r);
  231.  
  232.             while (running)
  233.             {
  234.                 WaitPort(win->UserPort);
  235.                 while (imsg = (struct IntuiMessage *) GetMsg(win->UserPort))
  236.                 {
  237.                     switch (imsg->Class)
  238.                     {
  239.                     case IDCMP_RAWKEY:
  240.                         switch (imsg->Code)
  241.                         {
  242.                         case 80:
  243.                             running = FALSE;
  244.                             break;
  245.                         }
  246.                         break;
  247.                     }
  248.                     ReplyMsg((struct Message *) imsg);
  249.                 }
  250.             }
  251.             CloseWindow(win);
  252.         }
  253.         else printf("Couldn't open window\n");
  254.         CloseScreen(scr);
  255.     }
  256.     else printf("Couldn't open screen\n");
  257. }
  258.  
  259.  
  260.